﻿using SQLMap.Core.Attributes;
using SQLMap.Core.Strategy;
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Xml;
/******************************************************************************************************************
 * 
 * 
 * 说　明： SqlMapConfig(版本：Version1.0.0)
 * 作　者：李朝强
 * 日　期：2015/05/19
 * 修　改：
 * 参　考：http://my.oschina.net/lichaoqiang/
 * 备　注：暂无...
 * 
 * 
 * ***************************************************************************************************************/
namespace SQLMap.Core
{

    /// <summary>
    /// <![CDATA[SqlMapConfig]]>
    /// </summary>
    public sealed class SqlMapConfig
    {

        /// <summary>
        /// <![CDATA[SQLMAP配置提供程序]]>
        /// </summary>
        public static SQLMap.Core.Provider.ISqlMapConfigProvider mapConfigProvider
        {
            get;
            private set;
        }

        /// <summary>
        /// <![CDATA[SQL解析器]]>
        /// </summary>
        public static ICommandParser commandParser { get; private set; }

        /// <summary>
        /// <![CDATA[静态构造函数]]>
        /// </summary>
        static SqlMapConfig()
        {
            mapConfigProvider = new SQLMap.Core.Provider.SqlMapConfigProvider();//默认
            commandParser = new Support.CommandParser();
        }

        /// <summary>
        /// <![CDATA[配置]]>
        /// </summary>
        public static void Configure()
        {
            string strBaseDirectory = AppDomain.CurrentDomain.BaseDirectory.Replace("bin\\", string.Empty).Replace("Debug", string.Empty).Replace("Release", string.Empty);
            string strSqlMapConfigFile = string.Empty;
            Assembly assemblyEntry = Assembly.GetEntryAssembly() ?? Assembly.GetCallingAssembly();
            object[] attributes = assemblyEntry.GetCustomAttributes(typeof(SQLMap.Core.Attributes.SqlMapConfigurationAttribute), false);
            if (null != attributes &&
                attributes.Any())
            {
                SqlMapConfigurationAttribute sqlMapConfigurationAttribute = (SqlMapConfigurationAttribute)attributes.First();
                if (string.IsNullOrEmpty(sqlMapConfigurationAttribute.ConfigFile) == false)
                {
                    strSqlMapConfigFile = System.IO.Path.Combine(strBaseDirectory, sqlMapConfigurationAttribute.ConfigFile);
                }
            }
            else
            {
                throw new FileNotFoundException("找不到SqlMap.config配置文件，请在程序集中配置“SQLMap.Core.Attributes.SqlMapConfigurationAttribute”");
            }
            //解析SqlMap配置文件
            using (XmlReader xmlReader = XmlReader.Create(strSqlMapConfigFile))
            {
                while (xmlReader.Read())
                {
                    if (xmlReader.NodeType == XmlNodeType.Element)
                    {
                        //Provider
                        if (xmlReader.Name == "provider")
                        {
                            string strProviderName = xmlReader.GetAttribute("name");
                            string strProviderType = xmlReader.GetAttribute("type");
                            if (strProviderName == "mapConfigProvider")
                            {
                                Type typeConfigProvider = Type.GetType(strProviderType);
                                mapConfigProvider = (SQLMap.Core.Provider.ISqlMapConfigProvider)Activator.CreateInstance(typeConfigProvider);
                            }
                            if (strProviderName == "commandParser")
                            {
                                Type commandParserType = Type.GetType(strProviderType);
                                commandParser = (Strategy.ICommandParser)Activator.CreateInstance(commandParserType);
                            }
                        }

                        //SQL-MAP 
                        if (xmlReader.Name == "sqlMap")
                        {
                            string strMap = xmlReader.GetAttribute("map");
                            Assembly assembly = Assembly.Load(strMap.Split(',')[1]);
                            //映射SQLMAP
                            mapConfigProvider.Configure(assembly, strMap.Split(',')[0]);
                        }

                    }
                }
            }

        }


    }
}
